﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Web;
using System.Web.Hosting;
using EPiServer.Web.Hosting;

namespace Hosting
{
    public class FlickrVirtualPathProvider : VirtualPathUnifiedProvider
    {
        private readonly FlickrDirectory _root;
        public string ServiceUrl { get; set; }

        public string PhysicalPath { get; set; }

        public FlickrVirtualPathProvider(string name, NameValueCollection config) : base(name, config)
        {
            PhysicalPath = config["physicalPath"];
            if (string.IsNullOrEmpty(PhysicalPath))
            {
                throw new ConfigurationErrorsException("FlickrVirtualPathProvider configuration missing or empty attribute 'physicalPath'");
            }

            ServiceUrl = config["flickrServiceUrl"];
            if (string.IsNullOrEmpty(ServiceUrl))
            {
                throw new ConfigurationErrorsException("FlickrVirtualPathProvider configuration missing or empty attribute 'flickrServiceUrl'");
            }

            ValidateAndSetupConfigParams();
            _root = new FlickrDirectory(this, VirtualPathUtility.AppendTrailingSlash(VirtualPathUtility.ToAbsolute(config["virtualPath"])), null);
        }

        public override bool DirectoryExists(string virtualDir)
        {
            if (virtualDir.StartsWith(_root.VirtualPath, StringComparison.InvariantCultureIgnoreCase))
            {
                return (FindDirectory(virtualDir) != null);
            }
            return Previous.DirectoryExists(virtualDir);

        }

        public override bool FileExists(string virtualPath)
        {
            if (virtualPath.StartsWith(this._root.VirtualPath, StringComparison.InvariantCultureIgnoreCase))
            {
                return (this.FindFile(virtualPath) != null);
            }
            return base.Previous.FileExists(virtualPath);
        }

        private FlickrFile FindFile(string virtualPath)
        {
            var fileName = VirtualPathUtility.GetFileName(virtualPath);
            var directory = FindDirectory(VirtualPathUtility.GetDirectory(virtualPath));
            if (directory == null)
            {
                directory = _root;
            }
            return directory.GetFile(fileName);
        }

        private FlickrDirectory FindDirectory(string virtualPath)
        {
            var directory = _root;
            var list = SplitVirtualPath(virtualPath, true);
            foreach (var str in list)
            {
                directory = directory.GetDirectory(str);
                if (directory == null)
                {
                    return null;
                }
            }
            return directory;
        }

        private List<string> SplitVirtualPath(string virtualPath, bool removeRoot)
        {
            if (removeRoot)
            {
                virtualPath = virtualPath.Remove(0, _root.VirtualPath.Length - 1);
            }
            return new List<string>(virtualPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries));
        }

        public override VirtualDirectory GetDirectory(string virtualDir)
        {
            if (virtualDir.StartsWith(_root.VirtualPath, StringComparison.InvariantCultureIgnoreCase))
            {
                return FindDirectory(virtualDir);
            }
            return Previous.GetDirectory(virtualDir);
        }

        public override VirtualFile GetFile(string virtualPath)
        {
            if (virtualPath.StartsWith(_root.VirtualPath, StringComparison.InvariantCultureIgnoreCase))
            {
                return FindFile(virtualPath);
            }
            return Previous.GetFile(virtualPath);
        }

    }
}
